package services;


import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;








import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;








import org.jboss.logging.Logger;

import sessionBeans.AdministradorMensajeria;
import sessionBeans.AdministradorModulo;
import sessionBeans.AdministradorOrdenDespacho;
import sessionBeans.AdministradorSolicitud;
import sessionBeans.AdministrarArticulo;
import xml.ArticuloXML;
import xml.RecibirSolicitudXML;
import xml.RespuestaXML;
import xml.SolicitudXML;
import dtos.ArticuloDTO;
import dtos.EstadosSolicitudDTO;
import dtos.ItemSolicitudDTO;
import dtos.ModuloDTO;
import dtos.OrdenDespachoDTO;
import dtos.OrdenPedidoDTO;
import dtos.ServiciosModuloDTO;
import dtos.SolicitudDTO;
import entities.Articulo;
import entities.EstadoSolicitud;
import entities.EstadoSolicitudValor;
import entities.ItemSolicitud;
import entities.Modulo;
import entities.OrdenDespacho;
import entities.ServiciosModulo;
import entities.Solicitud;
import exceptions.EntityAlreadyExistException;

@Stateless
public class AdministrarDespachoBean implements AdministrarDespacho {

	//@EJB(name="ejbModule.sessionBean.AdministradorModulo")
	@EJB
	private AdministradorModulo adminModulo;
	
	//@EJB(name="ejbModule.sessionBean.AdministrarArticulo")
	@EJB
	private AdministrarArticulo adminArt;
	
	@EJB
	private AdministradorSolicitud adminSol;
	
	@EJB
	private AdministradorOrdenDespacho adminOD;
	
	@EJB
	private AdministradorOrdenDespacho admDesp;
	
	@EJB
	private AdministradorMensajeria adminMensajeria;
	
    public AdministrarDespachoBean() {
        // TODO Auto-generated constructor stub
    }

    private Logger logger = Logger.getLogger(AdministrarDespachoBean.class);
	
    @Override
	public void CrearOrdenDeDespacho(OrdenPedidoDTO orden)
			throws EntityAlreadyExistException {
		
			// organizo las solicitudes por deposito
			List<Solicitud> listaSolicitud = adminSol
					.agruparSolicitudesPorDeposito(orden.getItems());

			// casteo el DTO a la orden despacho entiti
			OrdenDespacho ord = new OrdenDespacho();
			ord.setCodigoOrdenCompra(orden.getCodigoVenta());
			ord.setPortal(adminModulo.buscarModulo(orden.getIdPortal()
					.getId()));
			ord.setCodigo(orden.getCodigoDespacho());
			ord.setSolicitudes(listaSolicitud);
			ord.setCodigo(orden.getCodigoDespacho());

			// guardo la orden de despacho
			try {
				admDesp.CargarOrdenDespacho(ord);
			} catch (EntityAlreadyExistException e) {
				// TODO: handle exception
				throw new EntityAlreadyExistException(
						"ORDEN - Ya existe la ordne de despacho");
			}
			

			// Creo los xml de las sol
			for (Solicitud solAux : ord.getSolicitudes()) {
				SolicitudXML solXML = new SolicitudXML(solAux);
				String solicitudXML;
				JAXBContext jc;
				try {
					jc = JAXBContext.newInstance(SolicitudXML.class);
					javax.xml.bind.Marshaller m = jc.createMarshaller();
					m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
							Boolean.TRUE);
					java.io.StringWriter sw = new StringWriter();
					m.marshal(solXML, sw);
					System.out.println(sw.toString());
					if(!this.adminMensajeria.EnviarSolicitudADepositoSinAutenticacion(sw.toString(), solAux
							.getDeposito().getId()))
						{
						this.adminMensajeria.EnviarSolicitudADepositoConAutenticacion(sw.toString(), solAux
								.getDeposito().getId());
						};
				} catch (JAXBException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					Date fecha = Calendar.getInstance().getTime();
					logger.error("ERROR: Error creando xml de pedido nuevo (/n) EXCEPTION: "
							+ e.getStackTrace() + "(/n) FECHA: " + fecha);
				}

			}

		// llamar al adm de ord des y fijater si existe
		// si existe exepcion
		// si no existe llamo al amd de ord desp y la creo.
		// llamo al amd sol. y hago met crear sol, que recibe la lista de de sol
		// de la ord desp.
		// validar por cada solicitud ( tengo art y cantidad) agrupo por
		// deposito y artiulo, verifio que exista.
		// si no existe exception corrsp
		// agregarle a las ordn desp el estado pentiente
		// cuando termina, llamo al JMS de deposito y mandarle la solicitud.
		// (XML). metodo de mandar a deposito.

	}

    
	@Override
	public void CargarArticulo(String codigo, String descripcion, int idModulo) throws EntityAlreadyExistException {
		Modulo m = adminModulo.buscarModulo(idModulo);
		ModuloDTO mdto = new ModuloDTO();
		mdto = mdto.parseDTO(m);
		ArticuloDTO art = new ArticuloDTO(codigo, descripcion, mdto);
		adminArt.CargarArticulo(art);

	}

	@Override
	public void cargarSolicitud(SolicitudDTO s) {
		Modulo m = adminModulo.buscarModulo(s.getDeposito().getId());
		List<EstadoSolicitud> estados = new ArrayList<EstadoSolicitud>();
		List<ItemSolicitud> items = new ArrayList<ItemSolicitud>();
		for(EstadosSolicitudDTO es : s.getEstados()){
			EstadoSolicitud e = new EstadoSolicitud();
			e.setFecha(es.getFecha());
			e.setNombre(EstadoSolicitudValor.CONFIRMADA.toString());
			estados.add(e);
		}
		for(ItemSolicitudDTO i : s.getItems()){
			ItemSolicitud it = new ItemSolicitud();
			Articulo art = adminArt.buscarArticulo(i.getCodigoArticulo());
			it.setArticulo(art);
			it.setCantidad(i.getCantidad());
			items.add(it);
		}		
		Solicitud sol = new Solicitud();
		sol.setDeposito(m);
		sol.setEstados(estados);
		sol.setItems(items);
		try {
			adminSol.CargarSolicitud(sol);
		} catch (EntityAlreadyExistException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	@Override
	public List<SolicitudDTO> getSolicitudesPendientes() {
		// TODO Auto-generated method stub
		return adminSol.GetAllSolicitudesPendientesDTO();
	}
	
	public ServiciosModuloDTO buscarServicio(int servicio, int idModulo){
		return adminModulo.buscarServicioDTO(servicio, idModulo);
	}


	@Override
	public ModuloDTO getModuloActivo(String modulo) {
		// TODO Auto-generated method stub
		return adminModulo.getActivo(modulo);
	}


	@Override
	public RespuestaXML recibirSolicitudesJSON(RecibirSolicitudXML str) {
		// TODO Auto-generated method stub
		return adminOD.recibirSolicitudesJSON(str);
	}
	
	@Override
    public List<ModuloDTO> getAllModulo(){
    	return adminModulo.getAllModulo();
    }
    
    @Override
    public ModuloDTO getModulo(int codigo){
    	Modulo m = adminModulo.buscarModulo(codigo);
    	ModuloDTO resul = new ModuloDTO();
    	return resul.parseDTO(m);
    }


	@Override
	public boolean guardarModulo(ModuloDTO mod) {
		// TODO Auto-generated method stub
		return adminModulo.updateModulo(mod);
	}



	@Override
	public List<ArticuloDTO> getArticulos() {
		// TODO Auto-generated method stub
		return adminArt.GetAllArticulos();
	}



	@Override
	public List<SolicitudDTO> getSolicitudesPorEstado(int i) {
		// TODO Auto-generated method stub
		return adminSol.getSolicitudesPorEstado(i);
	}


	@Override
	public List<OrdenDespachoDTO> GetAllOrdenesDespacho() {
		// TODO Auto-generated method stub
		return adminOD.GetAllOrdenesDespacho();
	}


	@Override
	public void procesoOrdenes(Solicitud s) {
		adminOD.ProcesoOrdenes(s);
	}


	@Override
	public Solicitud buscarSolicitud(int codigo) {
		// TODO Auto-generated method stub
		return adminSol.buscarSolicitud(codigo);
	}

	
    

}
